package ejb.cbm.admin.session;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import ejb.cbm.admin.bean.ArchivoBean;
import ejb.cbm.admin.entity.ArchivoEntity;
import ejb.cbm.admin.entity.ArchivoLayoutEntity;
import ejb.cbm.admin.local.ArchivoSessionLocal;
import ejb.cbm.commons.JdbcHelper;

////@Stateless

@Service("archivoSessionLocal")
public class ArchivoSession extends HibernateDaoSupport implements ArchivoSessionLocal{
	
	static Logger logger = Logger.getLogger(ArchivoSession.class.getName());
	
	//property constants
	public static final String TIPOARCHIVO = "tipoarchivo";
	public static final String DESCRIPCION = "descripcion";
	public static final String NOMBREARCHIVO = "nombrearchivo";
	public static final String EXTENSION = "extension";
	public static final String RUTAENTRADA = "rutaentrada";
	public static final String RUTASALIDA = "rutasalida";
	public static final String TABLA = "tabla";
	public static final String SEQUENCE = "sequence";
	public static final String CORREOELECTRONICO = "correoelectronico";
	public static final String FLAGACTIVO = "flagactivo";
	public static final String USUARIOREGISTRO = "usuarioregistro";
	public static final String USUARIOMODIFICACION = "usuariomodificacion";
	
	@Autowired
	public ArchivoSession(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}

    ////@PersistenceContext 
    private EntityManager entityManager;
    
    @Transactional(propagation=Propagation.REQUIRED)
    public ArchivoEntity save(ArchivoEntity transientInstance) {
    	logger.info("saving ArchivoEntity instance");
        try {
            getSession().save(transientInstance);
            
            for (ArchivoLayoutEntity archivoLayoutEntity : transientInstance.getArchivolayouts()) {
            	archivoLayoutEntity.getId().setCodigoarchivo(transientInstance.getCodigoarchivo());
				getSession().save(archivoLayoutEntity);
			}
			
            //getSession().createQuery("delete from ArchivoLayoutEntity o where o.id.");
            //delete from TransaccionPerfilEntity o where  o.id.transaccionId = :transaccionId
            logger.info("save successful");
            return transientInstance;
        } catch (RuntimeException re) {
        	logger.fatal("save failed");
            throw re;
        }
    }

    @Transactional(propagation=Propagation.REQUIRED)
    public void delete(Serializable id) {
    	logger.info("deleting ArchivoEntity instance");
        try {
        	ArchivoEntity archivo = (ArchivoEntity)getSession().load(ArchivoEntity.class, id);
        	
            for (ArchivoLayoutEntity archivoLayoutEntity : archivo.getArchivolayouts()) {
				getSession().delete(archivoLayoutEntity);
			}
            getSession().delete(archivo);
            logger.info("delete successful");
        } catch (RuntimeException re) {
        	logger.fatal("delete failed");
            throw re;
        }
    }

    @Transactional(propagation=Propagation.REQUIRED)
    public ArchivoEntity update(ArchivoEntity detachedInstance) {
    	logger.info("updating ArchivoEntity instance");
        try {
        	// TODO: No aplica, por cambios a tablas externas
    		/*
        	
        	//Actualizamos los layouts
            List<Long> posiciones = new ArrayList<Long>();
        	for (ArchivoLayoutEntity layoutEntity : detachedInstance.getArchivolayouts()) {
        		posiciones.add(layoutEntity.getId().getPosicion());
        		layoutEntity.getId().setCodigoarchivo(detachedInstance.getCodigoarchivo());
        		getSession().merge(layoutEntity);
    		}
            
        	//Eliminamos los layouts que se eliminaron
        	String sql2 = "delete from ArchivoLayoutEntity o where o.id.codigoarchivo = :codigoarchivo ";
        	if(posiciones.size() > 0) {
        		sql2 += "and  o.id.posicion not in (:posicion)";
        	}
        	Query q2 = getSession().createQuery(sql2);
        	q2.setParameter("codigoarchivo", detachedInstance.getCodigoarchivo());
        	if(posiciones.size() > 0) {
        		q2.setParameterList("posicion", posiciones);
        	}
        	q2.executeUpdate();
        	*/
            ArchivoEntity result = (ArchivoEntity) getSession().merge(detachedInstance);
            
            logger.info("update successful");
            return result;
        } catch (RuntimeException re) {
        	logger.fatal("update failed");
            throw re;
        }
    }
    
    public ArchivoEntity findById( Serializable id) {
    	logger.info("finding ArchivoEntity instance with id: " + id);
        try {
            ArchivoEntity instance = (ArchivoEntity) getSession().get(ArchivoEntity.class, id);
            return instance;
        } catch (RuntimeException re) {
        	logger.fatal("find failed");
            throw re;
        }
    }
    
    //@SuppressWarnings("unchecked")
    public List<ArchivoEntity> findByProperty(String propertyName, Object value) {
    	logger.info("finding ArchivoEntity instance with property: " + propertyName
    						+ ", value: " );
		try {
			String queryString = "select model from ArchivoEntity model where model." 
			 						+ propertyName + "= :propertyValue";
			return getSession().createQuery(queryString).setParameter("propertyValue", value).list();
		} catch (RuntimeException re) {
			logger.fatal("find by property name failed");
			throw re;
		}
	}
	
	public List<ArchivoEntity> findByTipoarchivo(Object tipoarchivo) {
		return findByProperty(TIPOARCHIVO, tipoarchivo);
	}
	
	public List<ArchivoEntity> findByDescripcion(Object descripcion) {
		return findByProperty(DESCRIPCION, descripcion);
	}
	
	public List<ArchivoEntity> findByNombrearchivo(Object nombrearchivo) {
		return findByProperty(NOMBREARCHIVO, nombrearchivo);
	}
	
	public List<ArchivoEntity> findByExtension(Object extension) {
		return findByProperty(EXTENSION, extension);
	}
	
	public List<ArchivoEntity> findByRutaentrada(Object rutaentrada) {
		return findByProperty(RUTAENTRADA, rutaentrada);
	}
	
	public List<ArchivoEntity> findByRutasalida(Object rutasalida) {
		return findByProperty(RUTASALIDA, rutasalida);
	}
	
	public List<ArchivoEntity> findByTabla(Object tabla) {
		return findByProperty(TABLA, tabla);
	}
	
	public List<ArchivoEntity> findBySequence(Object sequence) {
		return findByProperty(SEQUENCE, sequence);
	}
	
	public List<ArchivoEntity> findByCorreoelectronico(Object correoelectronico) {
		return findByProperty(CORREOELECTRONICO, correoelectronico);
	}
	
	public List<ArchivoEntity> findByFlagactivo(Object flagactivo) {
		return findByProperty(FLAGACTIVO, flagactivo);
	}
	
	public List<ArchivoEntity> findByUsuarioregistro(Object usuarioregistro) {
		return findByProperty(USUARIOREGISTRO, usuarioregistro);
	}
	
	public List<ArchivoEntity> findByUsuariomodificacion(Object usuariomodificacion) {
		return findByProperty(USUARIOMODIFICACION, usuariomodificacion);
	}
	

	//@SuppressWarnings("unchecked")
	public List<ArchivoEntity> findAll() {
		logger.info("finding all ArchivoEntity instances");
		try {
			String queryString = "select model from ArchivoEntity model";
			return getSession().createQuery(queryString).list();
		} catch (RuntimeException re) {
			logger.fatal("find all failed");
			throw re;
		}
	}
	
	public List<ArchivoEntity> findByFiltro(ArchivoBean filtro){
		logger.info("UsuarioSession.findByFiltro UsuarioEntity instance");
		StringBuilder query = new StringBuilder();
		
		try{
			query.append(" select model ");
			query.append(" from ArchivoEntity model ");
			query.append(" where 1=1 ");
			
			if(filtro.getCodigoarchivo()!= null){
				query.append(" and model.codigoarchivo = "+filtro.getCodigoarchivo());
			}
			if(filtro.getDescripcion() != null){
				query.append(" and model.descripcion = "+JdbcHelper.to_char(filtro.getDescripcion()));
			}
			if(filtro.getExtension() != null){
				query.append(" and model.extension like "+JdbcHelper.to_char("%"+filtro.getExtension().trim().toUpperCase()+"%"));
			}
			if(filtro.getFlagactivo() != null){
				query.append(" and model.flagactivo = "+filtro.getFlagactivo());
			}
			if(filtro.getNombrearchivo()!= null){
				query.append(" and model.nombrearchivo like "+JdbcHelper.to_char("%"+filtro.getNombrearchivo().trim().toUpperCase()+"%"));
			}
			if(filtro.getRutaentrada()!= null){
				query.append(" and model.rutaentrada like "+JdbcHelper.to_char("%"+filtro.getRutaentrada().trim().toUpperCase()+"%"));
			}
			if(filtro.getRutasalida()!= null){
				query.append(" and model.rutasalida = "+JdbcHelper.to_char(filtro.getRutasalida()));
			}
			if(filtro.getTipoarchivo()!= null){
				query.append(" and model.tipoarchivo = "+filtro.getTipoarchivo());
			}

			return getSession().createQuery(query.toString()).list();
		
		}catch(RuntimeException e){
			logger.fatal("UsuarioSession.findByFiltro failed");
			throw e;
		}
	}
}